package com.qianfeng.iot.sdk.service.rabbitmq;

//
//                            _ooOoo_  
//                           o8888888o  
//                           88" . "88  
//                           (| -_- |)  
//                            O\ = /O  
//                        ____/`---'\____  
//                      .   ' \\| |// `.  
//                       / \\||| : |||// \  
//                     / _||||| -:- |||||- \  
//                       | | \\\ - /// | |  
//                     | \_| ''\---/'' | |  
//                      \ .-\__ `-` ___/-. /  
//                   ___`. .' /--.--\ `. . __  
//                ."" '< `.___\_<|>_/___.' >'"".  
//               | | : `- \`.;`\ _ /`;.`/ - ` : | |  
//                 \ \ `-. \_ __\ /__ _/ .-` / /  
//         ======`-.____`-.___\_____/___.-`____.-'======  
//                            `=---='  
//  
//         .............................................  
//                  佛祖镇楼                  BUG辟易  
//          佛曰:  
//                  写字楼里写字间，写字间里程序员；  
//                  程序人员写程序，又拿程序换酒钱。  
//                  酒醒只在网上坐，酒醉还来网下眠；  
//                  酒醉酒醒日复日，网上网下年复年。  
//                  但愿老死电脑间，不愿鞠躬老板前；  
//                  奔驰宝马贵者趣，公交自行程序员。  
//                  别人笑我忒疯癫，我笑自己命太贱；  
//  


import com.dc3.common.bean.driver.DriverConfiguration;
import com.dc3.common.bean.driver.DriverMetadata;
import com.dc3.common.constant.CommonConstant;
import com.dc3.common.model.*;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.qianfeng.iot.sdk.service.DriverMetaDataService;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * Created by Jackiechan on 2022/8/12 22:05
 *
 * @author Jackiechan
 * @version 1.0
 * @since 1.0
 */
@Component
@Slf4j
public class DriverMetaDataReceiver {

    private ObjectMapper objectMapper;

    @Autowired
    public void setObjectMapper(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }


    private DriverMetaDataService driverMetaDataService;

    @Autowired
    public void setDriverMetaDataService(DriverMetaDataService driverMetaDataService) {
        this.driverMetaDataService = driverMetaDataService;
    }


    @RabbitListener(queues = "#{driverEventQueue.name}")
    public void onDriverConfigMessage(Channel channel, Message message, DriverConfiguration driverConfiguration) {
        System.err.println("收到manager给我们回复的信息" + driverConfiguration);
        //先做一个应答,告诉服务器我们收到了
        try {
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);

        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        //根据发来的消息的类型来区分我们要做的事情
        switch (driverConfiguration.getType()) {
            case CommonConstant.Driver.Type.DRIVER:
                configurationDriverMeta(driverConfiguration);
                break;
            case CommonConstant.Driver.Type.POINT:
                configurationPoint(driverConfiguration);
                break;
            case CommonConstant.Driver.Type.POINT_INFO:
                configurationPointInfo(driverConfiguration);
                break;
            case CommonConstant.Driver.Type.DEVICE:
                configurationDevice(driverConfiguration);
                break;
            case CommonConstant.Driver.Type.DRIVER_INFO:
                configurationDriverInfo(driverConfiguration);
                break;
            case CommonConstant.Driver.Type.PROFILE:
                configurationProfile(driverConfiguration);
                break;

        }

    }

    private void configurationProfile(DriverConfiguration driverConfiguration) {
        try {
            Profile profile = objectMapper.readValue(objectMapper.writeValueAsString(driverConfiguration.getContent()), Profile.class);
            switch (driverConfiguration.getCommand()) {
                case CommonConstant.Driver.Profile.ADD:
                case CommonConstant.Driver.Profile.UPDATE:
                    driverMetaDataService.upsertProfile(profile);
                    break;
                case CommonConstant.Driver.Profile.DELETE:
                    driverMetaDataService.deleteProfile(profile.getId());
                    break;
            }
        }catch(JsonProcessingException e){
            throw new RuntimeException(e);
        }

    }

    private void configurationDriverInfo(DriverConfiguration driverConfiguration) {
        try {
            DriverInfo driverInfo = objectMapper.readValue(objectMapper.writeValueAsString(driverConfiguration.getContent()), DriverInfo.class);
            switch (driverConfiguration.getCommand()) {
                case CommonConstant.Driver.DriverInfo.ADD:
                case CommonConstant.Driver.DriverInfo.UPDATE:
                    driverMetaDataService.upsertDriverInfo(driverInfo);
                    break;
                case CommonConstant.Driver.DriverInfo.DELETE:
                    driverMetaDataService.deleteDriverInfo(driverInfo.getDeviceId(),driverInfo);
                    break;
            }
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }

    }

    private void configurationDevice(DriverConfiguration driverConfiguration) {
        try {
            Device device = objectMapper.readValue(objectMapper.writeValueAsString(driverConfiguration.getContent()), Device.class);
            switch (driverConfiguration.getCommand()) {
                case CommonConstant.Driver.Device.ADD:
                case CommonConstant.Driver.Device.UPDATE:
                    driverMetaDataService.upsertDevice(device);
                    break;
                case CommonConstant.Driver.Device.DELETE:
                    driverMetaDataService.deleteDevice(device.getId());
                    break;
            }
        }catch(JsonProcessingException e){
            throw new RuntimeException(e);
        }
    }

    private void configurationPointInfo(DriverConfiguration driverConfiguration) {
        try {
            PointInfo pointInfo = objectMapper.readValue(objectMapper.writeValueAsString(driverConfiguration.getContent()), PointInfo.class);
            switch (driverConfiguration.getCommand()) {
                case CommonConstant.Driver.Point.ADD:
                case CommonConstant.Driver.Point.UPDATE:
                    driverMetaDataService.upsertPointInfo(pointInfo);
                    break;
                case CommonConstant.Driver.Point.DELETE:
                    driverMetaDataService.deletePointInfo(pointInfo);
                    break;
            }
        }catch(JsonProcessingException e){
            throw new RuntimeException(e);
        }

    }

    private void configurationPoint(DriverConfiguration driverConfiguration) {

        try {
            Point point = objectMapper.readValue(objectMapper.writeValueAsString(driverConfiguration.getContent()), Point.class);
            switch (driverConfiguration.getCommand()) {
                case CommonConstant.Driver.Point.ADD:
                case CommonConstant.Driver.Point.UPDATE:
                    driverMetaDataService.upsertPoint(point);
                    break;
                case CommonConstant.Driver.Point.DELETE:
                    driverMetaDataService.deletePoint(point);
                    break;
            }
        }catch(JsonProcessingException e){
            throw new RuntimeException(e);
        }

    }

    /**
     * 配置驱动的元数据
     *
     * @param driverConfiguration
     */
    private void configurationDriverMeta(DriverConfiguration driverConfiguration) {
        //握手的返回对于我们来说问题不大, 注册的返回需要设置为在线状态,说明注册成功了,同步的返回会有数据,我们需要接收数据
        switch (driverConfiguration.getCommand()) {
            case CommonConstant.Driver.Event.DRIVER_REGISTER_BACK:
                /// driverContext.setDriverStatus(CommonConstant.Status.ONLINE);
                driverMetaDataService.updateDriverStatus(CommonConstant.Status.ONLINE);
                break;
            case CommonConstant.Driver.Event.DRIVER_METADATA_SYNC_BACK:
                //我们需要将数据更新到我们的conext中
                try {
                    driverMetaDataService.updateDriverMetaData(objectMapper.readValue(objectMapper.writeValueAsString(driverConfiguration.getContent()), DriverMetadata.class));
                } catch (JsonProcessingException e) {
                    throw new RuntimeException(e);
                }

                break;
        }
    }
}
